/**
 * 2010-2-25 
 * RelationService.java
 */
package com.snda.relation.service.relation.biz.service;

import com.snda.relation.service.exception.ServiceInvocationException;
import com.snda.relation.service.opensocial.GetResponse;
import com.snda.relation.service.opensocial.UpdateResponse;
import com.snda.relation.service.relation.biz.commons.CommonFriendsArray;
import com.snda.relation.service.relation.biz.commons.RelationType;
import com.snda.relation.service.relation.biz.domain.RelationFollow;
import com.snda.relation.service.relation.biz.domain.RelationReverse;
import com.snda.relation.service.relation.dal.domain.FansNumber;
import com.snda.commons.servicegate.annotations.Endpoint;
import com.snda.commons.servicegate.annotations.Param;
import com.snda.commons.servicegate.annotations.Service;
import com.snda.commons.servicegate.validation.Number;

/**
 * provide services of RelationFollowed and RelationFollow object model
 * 
 * @author yangjiandong
 * @since 2010-2-25
 * @file RelationService.java
 */
@Service("RelationService")
public interface RelationService {

	/**
	 * If (A follows B) then hostId = A, followerId = B;
	 * 
	 * @param hostId
	 * 
	 * @param followerId
	 * 
	 * @param appName
	 * 
	 * @param appId
	 * 
	 * @param remarks
	 * 
	 * @throws InvalidOperationException
	 */
	@Endpoint(alias = "addRelation")
	public UpdateResponse addRelation(
			@Param("hostId") @Number(min = 1) Long hostId,
			@Param("followerId") @Number(min = 1) Long followerId,
			@Param(value = "appId", defaultValue = "0", optional = true) Long appId,
			@Param(value = "remarks", defaultValue = "", optional = true) String remarks)
			throws ServiceInvocationException;

	/**
	 * 
	 * @param hostId
	 * @param followerId
	 * @param appId
	 * @param remarks
	 * @return
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "addRelationUnActivated")
	public UpdateResponse addRelationUnActivated(
			@Param("hostId") @Number(min = 1) Long hostId,
			@Param("followerId") @Number(min = 1) Long followerId,
			@Param(value = "appId", defaultValue = "0", optional = true) Long appId,
			@Param(value = "remarks", defaultValue = "", optional = true) String remarks)
			throws ServiceInvocationException;

	/**
	 * this API provides for game only
	 * 
	 * @param hostId
	 * @param followerId
	 * @param hostName
	 * 
	 * @param followerName
	 * 
	 * @param gameId
	 * 
	 * @param areaId
	 * 
	 * @param serverId
	 * 
	 * @param relationType
	 * 
	 * 
	 * @return
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "addRelationForGame")
	public UpdateResponse addRelationForGame(@Param("hostId") String hostId,
			@Param("followerId") String followerId,
			@Param("idType") Integer idType,
			@Param("hostName") String hostName,
			@Param("followerName") String followerName,
			@Param("gameId") Long gameId, @Param("areaId") Integer areaId,
			@Param("serverId") Integer serverId,
			@Param("relationType") Integer relationType)
			throws ServiceInvocationException;

	
	/**
	 * activate the already exist relation in the step 2
	 * @param sdid
	 * @return
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "activateRelation")
	public UpdateResponse activateRelation(@Param("sdid") Long sdid)
			throws ServiceInvocationException;
	
	
	/**
	 * this API provided for game only
	 * 
	 * @param hostId
	 * @param followerId
	 * @param relationType
	 * @return
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "deleteRelationForGame")
	public UpdateResponse deleteRelationForGame(@Param("hostId") String hostId,
			@Param("followerId") String followerId,
			@Param("idType") Integer idType,
			@Param("relationType") Integer relationType)
			throws ServiceInvocationException;

	/**
	 * If (A follows B) then hostId = A, followerId = B; this method do not
	 * remove the relation out of db, set the del-tag instead, find all the
	 * relationFollow(according to hostId, followerId),set the groupId 0
	 * 
	 * @param hostId
	 * @param followerId
	 * @throws InvalidOperationException
	 *             if hostId or follower is invalid
	 */
	@Endpoint(alias = "deleteRelation")
	public UpdateResponse deleteRelation(
			@Param("hostId") @Number(min = 1) Long hostId,
			@Param("followerId") @Number(min = 1) Long followerId)
			throws ServiceInvocationException;

	/**
	 * 
	 * 
	 * @param sdid
	 * @param commonFriendsNumber
	 * 
	 * @return
	 * @throws InvalidValueException
	 */
	@Endpoint(alias = "getCommonFriends")
	public GetResponse<CommonFriendsArray> searchCommonFriends(
			@Param("sdid") @Number(min = 1) Long sdid,
			@Param(value = "commonFriendsNumber", defaultValue = "0", optional = true) Integer commonFriendsNumber)
			throws ServiceInvocationException;

	/**
	 * get the list of RelationFollow (not including the groupId) objects of the
	 * sdid, return the list consists of the relationFollows from startIndex to
	 * (startIndex + count)
	 * 
	 * @param sdid
	 *            , startIndex, number
	 * @return list of RelationFollow objects, NULL if the ralationId was
	 *         invalid
	 * @throws InvalidOperationException
	 *             when sdid is invalid
	 * @throws DataAccessException
	 *             when one can not access the database
	 */
	@Endpoint(alias = "getRelationFollowDistinct")
	public GetResponse<RelationFollow> listRelationFollowDistinct(
			@Param("sdid") @Number(min = 1) Long sdid,
			@Param(value = "startIndex", defaultValue = "0", optional = true) Integer startIndex,
			@Param(value = "count", defaultValue = "0", optional = true) Integer count)
			throws ServiceInvocationException;

	/**
	 * get the list of RelationFollow (not including the groupId) objects of the
	 * sdid, return the list consists of the relationFollows from startIndex to
	 * (startIndex + count)
	 * 
	 * @param sdid
	 *            , startIndex, number
	 * @return list of RelationFollow objects, NULL if the ralationId was
	 *         invalid
	 * @throws InvalidOperationException
	 *             when sdid is invalid
	 * @throws DataAccessException
	 *             when one can not access the database
	 */
	@Endpoint(alias = "getRelationFollow")
	public GetResponse<RelationFollow> listRelationFollow(
			@Param("sdid") @Number(min = 1) Long sdid,
			@Param(value = "startIndex", defaultValue = "0", optional = true) Integer startIndex,
			@Param(value = "count", defaultValue = "0", optional = true) Integer count)
			throws ServiceInvocationException;

	/**
	 * sdid follows A,B,C; but A, B do not follow sdid, return the list contains
	 * A and B; to invate A, B to follow sdid
	 * 
	 * @param sdid
	 * @return
	 * @throws InvalidOperationException
	 * @throws DataAccessException
	 */
	@Endpoint(alias = "getRecommendPeople")
	public GetResponse<Long> listRecommendPeople(
			@Param("sdid") @Number(min = 1) Long sdid)
			throws ServiceInvocationException;

	/**
	 * list the list of people, who follows me but I don't follow them
	 * 
	 * @param sdid
	 * @return
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "getCandidatePeople")
	public GetResponse<Long> listCandidatePeople(
			@Param("sdid") @Number(min = 1) Long sdid)
			throws ServiceInvocationException;

	/**
	 * get the list of RelationReverse objects of the sdid, return the list
	 * consists of the relationReverses from startIndex to (startIndex + count)
	 * 
	 * @param sdid
	 * @return list of RelationFollowed objects, NULL if the ralationId was
	 *         invalid
	 * @throws InvalidOperationException
	 *             when sdid is invalid
	 * @throws DataAccessException
	 *             when one can not access the database
	 */
	@Endpoint(alias = "getRelationReverse")
	public GetResponse<RelationReverse> listRelationReverse(
			@Param("sdid") @Number(min = 1) Long sdid,
			@Param(value = "startIndex", defaultValue = "0") Integer startIndex,
			@Param(value = "count", defaultValue = "0") Integer count)
			throws ServiceInvocationException;

	/**
	 * TODO get the list of bi-relation of the sdid, return the list consists of
	 * the relationReverses from startIndex to (startIndex + count)
	 * 
	 * @retrun relationfollow or relationfollowed ? conside later
	 * @throws InvalidOperationException
	 *             when sdid is invalid
	 * @throws DataAccessException
	 *             when one can not access the database
	 */
	@Endpoint(alias = "getBiRelation")
	public GetResponse<RelationReverse> listBiRelation(
			@Param("sdid") @Number(min = 1) Long sdid,
			@Param(value = "startIndex", defaultValue = "0", optional = true) Integer startIndex,
			@Param(value = "count", defaultValue = "0", optional = true) Integer count)
			throws ServiceInvocationException;

	/**
	 * remove a relation(hostId follows followerId) out of a group
	 * 
	 * @param hostId
	 * @param followerId
	 * @param groupId
	 * @return 1 if success 0 when failure occurs
	 * @throws InvalidOperationException
	 * @throws DataAccessException
	 */
	@Endpoint(alias = "deleteRelationOutGroup")
	public UpdateResponse removeRelationOutGroup(
			@Param("hostId") @Number(min = 1) Long hostId,
			@Param("followerId") @Number(min = 1) Long followerId,
			@Param("groupId") Long groupId)
			throws ServiceInvocationException;

	/**
	 * according to (hostId, followerId, oldGrouId) to find a reltionFollow then
	 * modify the groupId to the newGroupId
	 * 
	 * @param hostId
	 * @param followerId
	 * @param groupId
	 * @return 1 if success 0 when failure occurs
	 * @throws InvalidOperationException
	 * @throws DataAccessException
	 */
	@Endpoint(alias = "updateRelationGroupId")
	public UpdateResponse modifyRelationGroupId(
			@Param("hostId") @Number(min = 1) Long hostId,
			@Param("followerId") @Number(min = 1) Long followerId,
			@Param("oldGroupId") Long oldGroupId,
			@Param("newGroupId") Long newGroupId)
			throws ServiceInvocationException;

	/**
	 * insert a relation to a group
	 * 
	 * @param hostId
	 * @param followerId
	 * @param gourpId
	 * @return 1 if success when failure occurs
	 * @throws InvalidOperationException
	 * @throws DataAccessException
	 */
	@Endpoint(alias = "addRelationToGroup")
	public UpdateResponse addRelationToGroup(
			@Param("hostId") @Number(min = 1) Long hostId,
			@Param("followerId") @Number(min = 1) Long followerId,
			@Param("groupId") Long groupId,
			@Param(value = "appId", defaultValue = "0", optional = true) Long appId,
			@Param(value = "remarks", defaultValue = " ", optional = true) String remarks)
			throws ServiceInvocationException;

	/**
	 * insert a relation to a group
	 * 
	 * @param hostId
	 * @param followerId
	 * @param gourpId
	 * @return 1 if success when failure occurs
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "getRelationType")
	public GetResponse<RelationType> judgeRelationType(
			@Param("sdid") @Number(min = 1) Long sdid,
			@Param("listOfSdid") Long[] listOfSdid,
			@Param("judgeType") Integer judgeType)
			throws ServiceInvocationException;

	/**
	 * move a followed person to the new list of group op: 1. delete this
	 * relation 2. add the relation to groups
	 * 
	 * @param hostId
	 * @param followerId
	 * @param listOfnewGroupId
	 * @return affectItems indicate the generated record number
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "updateRelationGroupIdByBatch")
	public UpdateResponse modifyRelationGroupIdByBatch(
			@Param("hostId") @Number(min = 1) Long hostId,
			@Param("followerId") @Number(min = 1) Long followerId,
			@Param("listOfnewGroupId") Long[] listOfnewGroupId)
			throws ServiceInvocationException;

	/**
	 * get the fans number of a list of sdids
	 * 
	 * @param sdids
	 * @return
	 * @throws ServiceInvocationException
	 */
	@Endpoint(alias = "getFansNumberByBatch")
	public GetResponse<FansNumber> listFansNumberByBatch(
			@Param("listOfSdid") Long[] listOfSdid)
			throws ServiceInvocationException;
}
